var ContextMenu = Class.create({
    initialize : function(map) {
        this.map = map;
        this.mapSize = new google.maps.Size(
            this.map.getDiv().offsetWidth,
            this.map.getDiv().offsetHeight
        );
        this.menu = this.renderMenu();
        this.hide();
        this.map.getDiv().appendChild(this.menu);
    },

    renderMenu : function() {
        var list = document.createElement('ul');
        list.style.position = 'absolute';
        list.style.zIndex = 1;
        list.style.font = 'small Arial';
        list.style.whiteSpace = 'nowrap';
        list.style.color = '#0000cd';
        list.style.backgroundColor = '#fff';
        list.style.listStyle = 'none';
        list.style.margin = '0px';
        list.style.padding = '0px';
        list.style.border = '1px solid #666';
        return list;
    },

    renderEntry : function(text, handler) {
        var self = this;
        var entry = document.createElement('li');
        entry.style.padding = '0px 6px';
        entry.style.lineHeight = '1.6em';
        entry.appendChild(document.createTextNode(text));

        google.maps.event.addDomListener(entry, 'mouseover', function() {
            entry.style.cursor = 'pointer';
            entry.style.backgroundColor = '#ccccdd';
        });

        google.maps.event.addDomListener(entry, 'mouseout', function() {
            entry.style.cursor = 'default';
            entry.style.backgroundColor = '#fff';
        });

        google.maps.event.addDomListener(entry, 'click', function() {
            if (handler)
                handler();
            self.hide();
        });
        return entry;
    },

    show : function(point, entriesModel) {
        var self = this;
        // Remove all entries
        while (self.menu.hasChildNodes())
            self.menu.removeChild(self.menu.firstChild);
        // Render all necessary entries
        entriesModel.each(function(entryModel) {
            var entry = self.renderEntry(entryModel.text, entryModel.handler);
            self.menu.appendChild(entry);
        });
        // Compute menu's position
        point.x -= self.menu.offsetWidth/2;
        point.y -= self.menu.offsetHeight/2;
        self.menu.style.left = Math.max(0, Math.min(point.x, self.mapSize.width-self.menu.offsetWidth));
        self.menu.style.top = Math.max(0, Math.min(point.y, self.mapSize.height-self.menu.offsetHeight));
        // Show menu
        self.menu.style.visibility = 'visible';
        self.menu.visible = true;
    },

    hide : function() {
        // Hide menu
        this.menu.style.visibility = 'hidden';
        this.menu.visible = false;
    }
});
